package jia.core.state;

import jia.game.GenericFlags;
import jia.temp.Caramon;
import jia.temp.Flint;
import jia.temp.Goldmoon;
import jia.temp.Riverwind;
import jia.temp.Sturm;
import jia.temp.Tanis;
import jia.core.EventProcessor;
import jia.core.GameStateManager;
import jia.core.UiManager;
import jia.core.characters.GameCharacter;
import jia.core.processors.BasicEventProcessor;
import org.apache.log4j.Logger;

/**
 * Primary manager for all things regarding the gamestate.  This class parents the
 * player's game characters and other settings.
 * @author Alec Lanter
 */
public class BasicGameStateManager implements GameStateManager{
    private static final Logger log = Logger.getLogger(BasicGameStateManager.class);
    private EventProcessor eventProcessor;
    private UiManager uiManager;
    private PlayerState playerState;
    private GameCharacter[] gameCharacters;
    
    /**
     * Default contructor that loads a basic manager with pre-poulated characters
     */
    public BasicGameStateManager(){
        playerState = new BasicPlayerState();
        eventProcessor = new BasicEventProcessor();
        gameCharacters = new GameCharacter[6];
        
        gameCharacters[0] = new Tanis().init();
        gameCharacters[1] = new Sturm().init();
        gameCharacters[2] = new Riverwind().init();
        gameCharacters[3] = new Flint().init();
        gameCharacters[4] = new Goldmoon().init();
        gameCharacters[5] = new Caramon().init();
        
        
    }
    
    /**
     * Contructor that accepts an array of GameCharacters.  This will happen prior to the
     * player starting a new game.  The admin screens will allow the user to select from
     * a pool of created GameCharacters.  That selection will populate the array which will in
     * turn be passed to this constructor when the player starts a game.
     * @param characters
     */
    public BasicGameStateManager(GameCharacter[] characters){
        playerState = new BasicPlayerState();
        eventProcessor = new BasicEventProcessor();
        gameCharacters = characters;
    }
    
    /**
     * Give the GameStateManager a hook into the EventProcessor
     * @see net.sf.jia.core.GameStateManager#registerEventProcessor(net.sf.jia.core.EventProcessor)
     */
    public void registerEventProcessor(EventProcessor ep){
        this.eventProcessor = ep;
    }
    
    /**
     * Give the GameStateManager a hook into the UiManager
     * @see net.sf.jia.core.GameStateManager#registerUiManager(net.sf.jia.core.UiManager)
     */
    public void registerUiManager(UiManager ui){
        ui.registerGameState(this);
        uiManager = ui;
    }
    
    /**
     * Returns the UiManager registered with this GameStateManager
     * @see net.sf.jia.core.GameStateManager#getUiManager()
     */
    public UiManager getUiManager(){
        return uiManager;
    }
    
    /**
     * Returns the EventProcessor registered with this GameStateManager
     * @see net.sf.jia.core.GameStateManager#getEventProcessor()
     */
    public EventProcessor getEventProcessor(){
        return eventProcessor;
    }
    
    /**
     * Returns the PlayerState
     * @see net.sf.jia.core.GameStateManager#getPlayerState()
     */
    public PlayerState getPlayerState(){
        return playerState;
    }
    
    /**
     * Method to call any time the game needs to respond to an action by the player.  If the
     * player moves to a square, or performs some other sort of action this method needs to
     * be called.
     * @see net.sf.jia.core.GameStateManager#notifyPlayerStateChanged()
     */
    public void notifyPlayerStateChanged(){
        if(GenericFlags.debugMessages) {
            log.debug("Notified of player state change.");
        }
        uiManager.notifyNeedUpdate();
        eventProcessor.processEvent(this, playerState.getCurrentModule().getSpace(playerState.getPosition()).getEvent());
        
        // TODO: Add a call to the event processor to check for events to process
    }
    
    /**
     * Returns an array of GameCharacters for this GameStateManager
     * @return
     */
    public GameCharacter[] getGameCharacters(){
        return gameCharacters;
    }
}
